package cn.djx.springsecurity.filter;

import cn.djx.springsecurity.constants.Constants;
import cn.djx.springsecurity.entity.LoginUsers;
import cn.djx.springsecurity.utils.RedisUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

@Configuration
public class AuthenticationTokenFilter extends OncePerRequestFilter {
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private ObjectMapper objectMapper;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 从请求头中获取token
        String  token = request.getHeader(Constants.header_token);
        if (!StringUtils.hasText(token)){
            // 如果请求头中没有token，则直接放行
            filterChain.doFilter(request, response);
            return;
        }
        // 解密 jwt token
        final JWT jwt = JWTUtil.parseToken(token);
        // 获取userid
        String key = jwt.getPayload("uid").toString();
        // 从Redis中获取用户信息
        String jsonLgoinUsers = (String) redisUtil.get(Constants.redis_token+key);
        if (!StringUtils.hasText(jsonLgoinUsers)){
            // 如果token不存在
            throw new ServletException("登录超时，请重新登录");
        }
        LoginUsers loginUsers = objectMapper.readValue(jsonLgoinUsers, LoginUsers.class);
        // 将token放入loginUsers中
        loginUsers.setToken(token);
        // 如果token存在，则将用户信息放入request中
        UsernamePasswordAuthenticationToken authenticationToken =
                //添加了用户权限
                new UsernamePasswordAuthenticationToken(loginUsers,null,loginUsers.getAuthorities());
        // 将用户信息放入SecurityContextHolder中
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        filterChain.doFilter(request, response);
    }
}
